﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Drawing;
using GifTools;
using System.Drawing.Imaging;
using BusinessClass.StateMachine.Core;
using BusinessClass.StateMachine.Core.Types;

namespace BusinessClass.StateMachine
{
    public class Machine
    {
        dynamic rules;
        string workingDir;
        string ttfPath;
        public Machine(String workingDir, string ttfPath)
        {
            this.workingDir = workingDir;
            this.ttfPath = ttfPath;
        }

        //{
        //    "name": "地图链接",
        //    "input": "",
        //    "sname": "dt.txt",
        //    "len": -1,
        //    "type": "txt",
        //    "format": "dtdz={0}"
        //}
        public string makeTxt(dynamic txtJson)
        {
            string outputFile;
            string name = txtJson.sname;
            string format = txtJson.format;
            string input = txtJson.input;
            outputFile = Common.conbindPath(workingDir, name);
            File.WriteAllText(outputFile,
                string.Format(format, input));
            return outputFile;
        }
        //        {
        //    "name": "地点",
        //    "input": "",
        //    "sname": "dd1;dd2",
        //    "len": 16,
        //    "type": "png",
        //    "width": "325",
        //    "height": "28",
        //    "fontsize": "15",
        //    "color": "#FFFF00",
        //    "backcolor": "#906d4f",
        //"oriOption": "V",
        //"posOption": "L"
        //}
        private IEnumerable<string> makePic(dynamic picJson, string txtRenderingHint)
        {
            List<string> outputFiles = new List<string>();
            int width = Convert.ToInt32(picJson.width);
            int height = Convert.ToInt32(picJson.height);
            int fontSize = Convert.ToInt32(picJson.fontsize);
            bool bold = Convert.ToBoolean(picJson.bold);
            string color = picJson.color;
            Color pen = color.ToColor();
            string bc = picJson.backcolor;
            Color backGroundPen = bc.ToColor();
            #region 构造Font
            Font f;
            FontBuilder fb = new FontBuilder(ttfPath, fontSize, bold);
            f = fb.TheFont;
            #endregion
            int limitedLen = Convert.ToInt32(picJson.len);
            string input = picJson.input;
            string sname = picJson.sname;
            DrawStringHelper.OriOptions oriOp = DrawStringHelper.OriOptions.H;
            if (((string)picJson.oriOption).ToUpper() == "V")
                oriOp = DrawStringHelper.OriOptions.V;
            DrawStringHelper.Hor hor = DrawStringHelper.Hor.C;
            if (((string)picJson.hor).ToUpper() == "R")
            {
                hor = DrawStringHelper.Hor.R;
            }
            else if (((string)picJson.hor).ToUpper() == "L")
            {
                hor = DrawStringHelper.Hor.L;
            }
            DrawStringHelper.Ver ver = DrawStringHelper.Ver.C;
            if (((string)picJson.ver).ToUpper() == "T")
            {
                ver = DrawStringHelper.Ver.T;
            }
            else if (((string)picJson.ver).ToUpper() == "B")
            {
                ver = DrawStringHelper.Ver.B;
            }
            if (sname.IndexOf(";") > 0)
            {
                var names = sname.Split(';');
                int i = 0;
                while (input.Length > limitedLen)
                {
                    string t = input.Substring(0, limitedLen);
                    string outPutPath = Common.conbindPath(workingDir, names[i++]);
                    outputFiles.Add(make(oriOp, hor, ver, width, height, pen, backGroundPen, t, f, txtRenderingHint, outPutPath));
                    input = input.Substring(limitedLen);
                }
                if (input.Length > 0)
                {
                    string outPutPath = Common.conbindPath(workingDir, names[i++]);
                    outputFiles.Add(make(oriOp, hor, ver, width, height, pen, backGroundPen, input, f, txtRenderingHint, outPutPath));
                }
                while (i < names.Length)
                {
                    string outPutPath = Common.conbindPath(workingDir, names[i++]);
                    outputFiles.Add(make(oriOp, hor, ver, width, height, pen, backGroundPen, " ", f, txtRenderingHint, outPutPath));

                }
            }
            else
            {
                string outPutPath = Common.conbindPath(workingDir, sname);
                outputFiles.Add(make(oriOp, hor, ver, width, height, pen, backGroundPen, input, f, txtRenderingHint, outPutPath));
            }
            return outputFiles;
        }
        private string make(DrawStringHelper.OriOptions oriOp, DrawStringHelper.Hor hor, DrawStringHelper.Ver ver, int width, int height, Color pen, Color backGroundPen, string text, Font f, string txtRenderingHint, string outPutPath)
        {
            Bitmap canvas = new Bitmap(width, height);
            Brush penBrush = new SolidBrush(pen);
            using (Graphics g = Graphics.FromImage(canvas))
            {
                //g.Clear(backGroundPen);
                //g.Save();
                g.FillRectangle(new SolidBrush(backGroundPen), 0, 0, width, height);
                g.Save();
            }
            canvas = DrawStringHelper.drawNew(text, canvas, f, penBrush, backGroundPen, oriOp, hor, ver, txtRenderingHint);
            canvas.MakeTransparent(backGroundPen);
            canvas.Save(outPutPath, ImageFormat.Png);
            return outPutPath;
        }
        /// <summary>
        /// 定制make.bat,然后调用。
        /// </summary>
        /// <param name="exeName"></param>
        void dabao(string WorkingDir, string exeName)
        {
            #region 定制make.bat
            var mobanExeName = Directory.EnumerateFiles(WorkingDir, "*.exe").First();
            mobanExeName = Common.getFileName(mobanExeName);
            var cmdPath = Common.conbindPath(WorkingDir, "make.bat");
            var bat = File.ReadAllText(cmdPath, Encoding.Default);
            var cmd =
                bat.Replace("winrarPath", Properties.Settings.Default.winrarPath)
                .Replace("exeName", exeName)
                .Replace("mobanExeName", mobanExeName);
            File.WriteAllText(cmdPath, cmd, Encoding.Default);
            #endregion
            #region 定制info.txt
            File.AppendAllText(Common.conbindPath(WorkingDir, "info.txt"), mobanExeName, Encoding.Default);
            #endregion
            System.Diagnostics.ProcessStartInfo info = new System.Diagnostics.ProcessStartInfo(cmdPath);
            info.WorkingDirectory = Common.getDir(cmdPath);
            var p = System.Diagnostics.Process.Start(info);
            p.WaitForExit();
        }

        public T Visit<T>(ISate<T> state)
        {
            return state.Accept(this);
        }
        public IEnumerable<string> VisitMakePic(MakePicState makePicState)
        {
            return makePic(makePicState.Config, makePicState.TxtRenderingHint);
        }

        public string VisitMakeTxt(MakeTxtPicState makeTxtState)
        {
            return makeTxt(makeTxtState.Config);
        }

        public Unit VisitPackage(PackageState packageState)
        {
            dabao(packageState.WorkingDir, packageState.ExeName);
            return new Unit();
        }

        public string VisitMakeFile(MakeFileState makeFileState)
        {
            return makeTxt(makeFileState.Config);
        }

        public void VisitDeleteTempFiles(DeleteTempFilesState deleteTempFilesState)
        {
            FileHelper.DeleteTempFile(deleteTempFilesState.Files);
        }

        public T VisitAction<T>(ActionSate<T> actionSate)
        {
            return actionSate.Action();
        }
    }
}
